export interface IState {
  [key: string]: any;
}

export interface ISelect<TState = any, TSelected = any> {
  (selector: ISelector<TState, TSelected>): TSelected;
}

export interface IUpdate<T extends Object> {
  (namespace: string, state: T): void;
}

export interface IPut<T = any> {
  (params: IDispatchParams): Promise<T>;
}

export interface IAll<T = any> {
  (funcList: Promise<T>[]): Promise<Awaited<T>[]>;
}

export interface IActionParams {
  select: ISelect;
  update: IUpdate<any>;
  put: IPut;
  all: IAll;
}

export interface IAction<T = any> {
  (dispatchParams: IDispatchParams, actionParams: IActionParams): Promise<T>;
}

export interface IModel<T = IState, F = IAction> {
  states: T;
  actions: F;
}

export interface IDispatchParams {
  type: string;
  payload?: any;
  [key: string]: any;
}

export interface IDispatch {
  (params: IDispatchParams): Promise<any>;
}
export interface ISelector<TState = any, TSelected = any> {
  (state: TState): TSelected;
}
